package org.example.java.util.concurrency;

import java.util.concurrent.TimeUnit;

/**
 * User: ZhangJuntao
 * Date: 13-12-13
 * Time: 上午7:53
 */
public class ThreadWaitSleepTest implements Runnable {
  static class Lock {
    private String time;
  }

  private final Lock lock = new Lock();

//  public ThreadWaitSleepTest(String name) {
//    super(name);
//  }


  @Override
  public String toString() {
    return "ThreadWaitSleepTest{" +
        "lock=" + lock.time +
        '}';
  }

  private void lock() throws InterruptedException {
    System.out.printf("%s before lock lock.%n", this.toString());
    synchronized (lock) {
      System.out.printf("%s lock lock.%n", this.toString());
      lock.time = String.valueOf(System.currentTimeMillis());
      lock.wait(); //线程在获取对象锁后，主动释放对象锁，同时本线程休眠
//      TimeUnit.MILLISECONDS.sleep(2000);
//      lock.notify();
    }
    System.out.printf("%s after lock lock.%n", this.toString());
  }

  @Override
  public void run() {
    try {
      this.lock();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) throws InterruptedException {
    final ThreadWaitSleepTest run = new ThreadWaitSleepTest();
    Thread test1 = new Thread(run, "Thread1");
    Thread test2 = new Thread(run, "Thread2");
    test1.start();
    test2.start();
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        try {
          System.out.println(Thread.currentThread().getName() + " run");
          TimeUnit.SECONDS.sleep(1);
          synchronized (run.lock) {
            System.out.println(Thread.currentThread().getName() + " lock start");
            System.out.println(run.lock.time);
            TimeUnit.SECONDS.sleep(1);
            run.lock.time = Thread.currentThread().getName() + " " + System.currentTimeMillis();
            run.lock.notify();
            System.out.println(run.lock.time);
            System.out.println(Thread.currentThread().getName() + " lock end");
          }
          System.out.println(Thread.currentThread().getName() + " end");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
    Runnable runnable2 = new Runnable() {
      @Override
      public void run() {
        try {
          System.out.println(Thread.currentThread().getName() + " run");
          TimeUnit.SECONDS.sleep(1);
          synchronized (run.lock) {
            System.out.println(Thread.currentThread().getName() + " lock start");
            System.out.println(run.lock.time);
            TimeUnit.SECONDS.sleep(1);
            run.lock.time = Thread.currentThread().getName() + " " + System.currentTimeMillis();
            run.lock.notify();
            System.out.println(run.lock.time);
            System.out.println(Thread.currentThread().getName() + " lock end");
          }
          System.out.println(Thread.currentThread().getName() + " end");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    };
    new Thread(runnable).start();
    TimeUnit.SECONDS.sleep(1);
    run.lock.time="ddddd";
    new Thread(runnable2).start();
  }
}
